*Please note that I applied Professor Guttag's code to something that's applicable to me so this work is not really mine.

Let's create something to help us make smart shopping decisions. First, I want to create a class that examplifies the value (how much do I want the product), price, and desire (something normalized; value/price)

In [1]:
class Clothes(object):
    def __init__(self, n, v, p):
        self.name = n
        self.value = v
        self.price = p
    def getValue(self):
        return self.value
    def getPrice(self):
        return self.price
    def getDesire(self):
        return self.getValue()/self.getPrice()
    def __str__(self):
        return self.name + ': <' + str(self.value) + ', ' + str(self.price) + '>'

Let's build our shopping cart

In [2]:
def buildShoppingCart(names, values, prices):
    """names, values, prices lists of same length.
    name a list of strings
    values and prices lists of numbers
    returns lists of Clothes"""
    ShoppingCart = []
    for i in range(len(values)):
        ShoppingCart.append(Clothes(names[i], values[i], prices[i]))
    return ShoppingCart

Let's sort our items depending on what's important to us. Let's also total up the price and value to see how happy we'll be overall with our shopping decisions.

In [3]:
def greedy(items, maxCost, keyFunction):
    """Assumes items a list, maxCost >= 0,
    keyFunction maps elements of items to numbers"""
    itemsCopy = sorted(items, key = keyFunction, reverse=True)
    result = []
    totalValue, totalPrice = 0.0, 0.0
    for i in range(len(itemsCopy)):
        if(totalPrice+itemsCopy[i].getPrice()) <= maxCost:
            result.append(itemsCopy[i])
            totalPrice += itemsCopy[i].getPrice()
            totalValue += itemsCopy[i].getValue()
    return (result, totalValue)

The output for out code.

In [5]:
def testGreedy(items, constraint, keyFunction):
    taken, val = greedy(items, constraint, keyFunction)
    print('Total value of items taken =', val)
    for item in taken:
        print(' ', item)
def testGreedys(clothes, maxUnits):
    print('Use greedy by value to allocate', maxUnits, 'price')
    testGreedy(clothes, maxUnits, Clothes.getValue)
    print('\nUse greedy by cost to allocate', maxUnits, 'price')
    testGreedy(clothes, maxUnits, lambda x: 1/Clothes.getPrice(x))
    print('\nUse greedy by desire to allocate', maxUnits, 'price')
    testGreedy(clothes, maxUnits, Clothes.getDesire)

Let's make a sample set and test out our code. Let's pretend we only have $150 to spend as well for our test.

In [6]:
names = ['red dress', 'sunny dress', 'running sneakers', 'shorts', 'bathing suit', 'baseball cap']
prices = [90, 90, 60, 20, 20, 10]
values = [100, 70, 70, 90, 60, 20]
clothes = buildShoppingCart(names, values, prices)
testGreedys(clothes, 150)
Use greedy by value to allocate 150 price
Total value of items taken = 270.0
  red dress: <100, 90>
  shorts: <90, 20>
  bathing suit: <60, 20>
  baseball cap: <20, 10>

Use greedy by cost to allocate 150 price
Total value of items taken = 240.0
  baseball cap: <20, 10>
  shorts: <90, 20>
  bathing suit: <60, 20>
  running sneakers: <70, 60>

Use greedy by desire to allocate 150 price
Total value of items taken = 240.0
  shorts: <90, 20>
  bathing suit: <60, 20>
  baseball cap: <20, 10>
  running sneakers: <70, 60>

And voila, now you can compare the different items to shop for optimal happiness.